<template>
  <view class="content">
    <view class="upload-wrapper">
      <view class="upload-btn-container">
        <up-button :customStyle="{ width: '200rpx' }" type="primary" text="上传附件" @tap="triggerUpload"></up-button>
        <xe-upload ref="XeUpload" :options="uploadOptions" name="file" @beforUpload="beforUpload"
          @callback="handleUploadCallback" style="display:none"></xe-upload>

        <!-- 上传进度条 -->
        <view class="progress-container" v-if="isUploading">
          <view class="progress-bar">
            <view class="progress-fill" :style="{ width: uploadProgress + '%' }"></view>
          </view>
          <text class="progress-text">{{ uploadProgress }}%</text>
        </view>
      </view>

      <!-- 文件列表独立展示 -->
      <view class="file-list-container">
        <view class="file-item" v-for="(item, index) in fileList" :key="item.id || item.uuid || index">
          <text class="file-name" @click="FileViewClick(item)">{{ item.name }}</text>
          <view class="remove-btn" @click="clear(item.name)">
            <up-icon name="close-circle-fill" size="20" color="#ff4d4f"></up-icon>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
import { useUserStore } from '@/pinia-store/user'
import { COMMON_API_BASE_URL } from '@/utils/request'
import { mapStores } from 'pinia'
import { ProcessingURL, viewFile } from '@/utils/publicmethod.js'
export default {
  name: 'UploadFileLsjToXe',
  props: {
    itemIndex: {
      type: Number,
      default: 0
    },
    value: {
      type: String,
      default: null
    },
    format: {
      type: String,
      default: ''
    },
    title: {
      type: String,
      default: ''
    },
    ApplyDetailList: {
      type: Array,
      default: () => []
    },
    itemId: {
      type: String,
      required: true
    }
  },
  data () {
    return {
      // xe-upload 配置（会在 created 填充 token）
      uploadOptions: {
        url: `${COMMON_API_BASE_URL}/dist/interface/public/index.php/form/Form/upload`,
        name: 'file',
        formData: {}
      },
      // 通用限制（与原 lsj 保持一致）
      formats: 'docx,doc,pdf,jpeg,jpg,png,gif,ppt,pptx,xls,xlsx',
      sizeLimit: 30, // MB
      countLimit: 5,

      // 文件回显/缓存与进度
      filesMap: new Map(), // 未必需要但保留以便扩展
      fileList: [],
      isUploading: false,
      uploadProgress: 0,
      nextCloud: {}
    }
  },
  computed: {
    ...mapStores(useUserStore)
  },
  created () {
    // 填充 token 到 options（确保后端能收到 token）
    const token = uni.getStorageSync('token') || this.userStore.user.token
    this.uploadOptions.formData = { token }
    this.nextCloud = uni.getStorageSync('next_cloud') || {}
    this.loadCache()
  },
  mounted () {
    let value = uni.getStorageSync('formData');
    let formItems = JSON.parse(value.formItems);
    formItems.forEach(item => {
      if (item.title == this.title) {
        uni.removeStorageSync(`${item.id}`);
      }
    })

    this.setechodata()
  },
  watch: {
    fileList: {
      handler (newValue) {
        let value = uni.getStorageSync('formData');
        let formItems = JSON.parse(value.formItems);
        formItems.forEach(item => {
          if (item.title == this.title) {
            // item.value = newValue;
            // uni.setStorageSync(item.id, newValue);
            item.value = newValue.map(file => ({
              ...file,
              url: file.originalUrl || file.url
            }));
            uni.setStorageSync(item.id, item.value);
          }
        })
      },
      deep: true
    }
  },
  methods: {
    setechodata () {
      // 添加数据回显逻辑
      if (this.ApplyDetailList && this.ApplyDetailList.formData && this.itemId) {
        if (this.ApplyDetailList.formData.hasOwnProperty(this.itemId)) {
          const fieldValue = this.ApplyDetailList.formData[this.itemId];
          if (Array.isArray(fieldValue) && fieldValue.length > 0) {
            this.fileList = fieldValue
          }
        }
      }
    },
    triggerUpload () {
      const count = this.countLimit - this.fileList.length
      if (count <= 0) return uni.showToast({ title: '已达最大上传数量', icon: 'none' })

      // #ifdef APP-PLUS
      if (this.$refs.XeUpload && this.$refs.XeUpload.upload) {
        this.$refs.XeUpload.upload('file') // 调起文件选择并上传（xe-upload 内部处理）
      } else if (this.$refs.XeUpload && this.$refs.XeUpload.show) {
        this.$refs.XeUpload.show()
      }
      // #endif

      // #ifdef H5
      uni.chooseFile({
        count,
        type: 'all',
        extension: this.formats.split(','),
        success: (res) => {
          res.tempFiles.forEach(file => {
            if (file.size > this.sizeLimit * 1024 * 1024) {
              uni.showToast({ title: `${file.name} 超过大小限制`, icon: 'none' })
              return
            }
            this.h5UploadFile(file)
          })
        }
      })
      // #endif
    },
    h5UploadFile (file) {
      this.isUploading = true
      const token = uni.getStorageSync('token') || this.userStore.user.token
      const uploadTask = uni.uploadFile({
        url: this.uploadOptions.url,
        filePath: file.path || file.tempFilePath,
        name: this.uploadOptions.name || 'file',
        formData: { token },
        success: (res) => {
          try {
            const data = JSON.parse(res.data)
            if (data && (data.status === 1)) {
              const fileData = {
                ...data.data,
                id: data.data.id || data.data.fid || data.data.file_id || '',
                name: data.data.name || file.name,
                size: file.size,
                status: 'done',
                url: ProcessingURL(data.data.url),
                originalUrl: data.data.url,
                progress: 100
              }
              this.fileList.push(fileData)
            } else {
              uni.showToast({ title: '上传失败', icon: 'none' })
            }
          } catch (e) {
            console.error('解析上传结果失败', e)
            uni.showToast({ title: '解析上传结果失败', icon: 'none' })
          }
        },
        fail: (err) => {
          console.error('upload error', err)
          uni.showToast({ title: '上传出错', icon: 'none' })
        },
        complete: () => {
          this.isUploading = false
          this.uploadProgress = 0
        }
      })

      // 进度
      uploadTask.onProgressUpdate((progress) => {
        this.uploadProgress = progress.progress
        if (progress.progress >= 100) {
          setTimeout(() => {
            this.isUploading = false
            this.uploadProgress = 0
          }, 500)
        }
      })
    },

    beforUpload (e) {
      const tempFile = {
        uuid: e.uuid,
        name: e.fileName,
        size: e.fileSize,
        status: 'uploading',
        url: '',
        originalUrl: '',
        progress: 0,
        id: '' // 以后填充 id
      }
      this.fileList.push(tempFile)
      this.isUploading = true
      this.uploadProgress = 0
    },
    handleUploadCallback (e) {
      // 进度回调
      if (e.type === 'onprogress') {
        const progress = e.data?.progress || e.data?.[0]?.progress || 0
        // 更新全局进度（也可以只对单条更新）
        this.uploadProgress = progress
        // console.log('this.uploadProgress', this.uploadProgress);

        // 更新对应的临时文件的 progress
        const uuid = e.data?.uuid || (e.data && e.data[0] && e.data[0].uuid)
        if (uuid) {
          const idx = this.fileList.findIndex(f => f.uuid === uuid)
          if (idx !== -1) this.fileList[idx].progress = this.uploadProgress
        }
        return
      }

      // 成功回调
      if (e.type === 'success') {
        const uuid = e.data?.uuid
        const fileNode = e.data?.[0] || e.data

        // 找到对应的临时文件
        const idx = this.fileList.findIndex(f => f.uuid === uuid)
        if (idx === -1) {
          const resp = fileNode?.response || {}
          const respData = resp?.data || (resp?.responseText ? JSON.parse(resp.responseText).data : null)
          const fallback = {
            uuid,
            id: respData?.id || '',
            name: fileNode?.name || respData?.name || 'file',
            size: fileNode?.size || respData?.size || 0,
            url: ProcessingURL(respData?.url || ''),
            originalUrl: respData?.url || '',
            status: respData ? 'done' : 'error',
            progress: 100
          }
          this.fileList.push(fallback)
          this.persistAndEmit()
          this.isUploading = false
          this.uploadProgress = 0
          return
        }

        const fileItem = this.fileList[idx]
        const response = fileNode?.response || {}
        let responseData = null
        if (typeof response === 'string' && response) {
          try { responseData = JSON.parse(response) } catch (e) { responseData = null }
        } else if (response && response.data) {
          responseData = response
        } else if (fileNode && fileNode.responseText) {
          try { responseData = JSON.parse(fileNode.responseText) } catch (ex) { responseData = null }
        } else {
          responseData = response
        }

        if (responseData && (responseData.status === 1)) {
          const data = responseData.data || {}
          fileItem.status = 'done'
          fileItem.id = data.id || data.fid || fileItem.id || ''
          fileItem.name = data.name || fileItem.name
          fileItem.size = data.size || fileItem.size
          fileItem.url = ProcessingURL(data.url || data.path || fileItem.originalUrl || fileItem.url)
          fileItem.originalUrl = data.url || fileItem.originalUrl || fileItem.url
          fileItem.progress = 100

          this.persistAndEmit()
        } else {
          const msg = (responseData && responseData.msg) ? responseData.msg : '上传失败'
          uni.showToast({ title: msg, icon: 'none' })
          fileItem.status = 'error'
          this.persistAndEmit()
        }

        this.isUploading = false
        this.uploadProgress = 0
        return
      }

      // 错误回调
      if (e.type === 'error') {
        uni.showToast({ title: '上传出错', icon: 'none' })
        this.isUploading = false
        this.uploadProgress = 0
      }
    },

    // 删除单个文件（或全部）
    clear (name) {
      if (!name) {
        this.fileList = []
      } else {
        const findIndex = this.fileList.findIndex(item => item.name === name)
        if (findIndex !== -1) this.fileList.splice(findIndex, 1)
      }
      this.persistAndEmit()
    },

    persistAndEmit () {
      const toSave = this.fileList.map(file => ({
        ...file,
        url: file.originalUrl || file.url
      }))
      uni.setStorageSync(this.itemId, toSave)

      // 通知父组件（ok + orderAfterSales） —— 保持与老司机行为一致
      this.$emit('ok', { fileList: this.fileList, index: this.itemIndex })
      this.$emit('orderAfterSales', { fileList: this.fileList, index: this.itemIndex })
    },

    loadCache () {
      try {
        const cached = uni.getStorageSync(this.itemId)
        if (cached && Array.isArray(cached) && cached.length > 0) {
          this.fileList = cached.map(f => ({
            ...f,
            originalUrl: f.url || f.originalUrl,
            url: f.url || f.originalUrl,
            status: f.status || 'done',
            progress: f.progress || 100
          }))
        }
      } catch (e) {
        console.warn('读取缓存失败', e)
      }
    },
    FileViewClick (item) {
      viewFile(item, {
        fileList: this.fileList,
        userStore: this.userStore,
        xtoken: this.nextCloud?.xtoken,
      });
    },
  }
}
</script>

<style scoped>
.content {
  padding: 5rpx;
}

.upload-wrapper {
  display: flex;
  flex-direction: column;
}

.upload-btn-container {
  width: 200rpx;
}

.progress-container {
  margin-top: 20rpx;
  width: 100%;
}

.progress-bar {
  width: 100%;
  height: 8rpx;
  background-color: #e4e7ed;
  border-radius: 4rpx;
  overflow: hidden;
  position: relative;
}

.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #409eff 0%, #67c23a 100%);
  border-radius: 4rpx;
  transition: width 0.3s ease;
  position: relative;
}

.progress-text {
  font-size: 24rpx;
  color: #606266;
  margin-top: 8rpx;
  text-align: center;
  display: block;
}

.file-list-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 15rpx;
  margin-top: 15rpx;
}

.file-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 15rpx;
  background-color: #f8f8f8;
  border-radius: 8rpx;
  width: 90vw;
}

.file-name {
  flex: 1;
  color: #333;
  font-size: 28rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.delete-btn {
  color: #fff;
  background-color: #f56c6c;
  padding: 8rpx 20rpx;
  border-radius: 6rpx;
  font-size: 24rpx;
  margin-left: 20rpx;
}
</style>
